package com.huiminpay.paymentagent.service;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.paymentagent.api.PayChannelAgentService;
import com.huiminpay.paymentagent.api.conf.AliConfigParam;
import com.huiminpay.paymentagent.api.dto.AlipayBean;
import com.huiminpay.paymentagent.api.dto.PaymentResponseDTO;
import com.huiminpay.paymentagent.api.dto.TradeStatus;
import com.huiminpay.paymentagent.common.constant.AliCodeConstants;
import com.huiminpay.paymentagent.message.PayProducer;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;

import javax.annotation.Resource;

/**
 * ClassName:PayChannelAgentServiceImpl
 * Package:com.huiminpay.paymentagent.service
 * Time: 2024/7/29
 */
@Service // 声明为dubbo服务
@Slf4j
public class PayChannelAgentServiceImpl implements PayChannelAgentService {

    @Resource
    PayProducer payProducer; // 支付消息生产者

    /**
     * 调用支付宝手机WAP下单接口
     *
     * @param aliConfigParam 支付渠道参数
     * @param alipayBean     请求支付参数
     * @return 支付响应结果
     * @throws BusinessException
     */
    @Override
    public PaymentResponseDTO createPayOrderByAliWAP(AliConfigParam aliConfigParam, AlipayBean alipayBean) throws BusinessException {
        log.info("支付宝请求参数", alipayBean.toString());

        //支付宝渠道参数
        String gateway = aliConfigParam.getUrl(); //支付宝下单接口地址,支付宝网关
        String appId = aliConfigParam.getAppId(); //支付宝应用ID
        String rsaPrivateKey = aliConfigParam.getRsaPrivateKey(); //商户私钥
        String format = aliConfigParam.getFormat(); //请求参数格式
        String charset = aliConfigParam.getCharset(); //编码格式
        String alipayPublicKey = aliConfigParam.getAlipayPublicKey(); //支付宝公钥
        String signType = aliConfigParam.getSigntype(); //签名方式
        String notifyUrl = aliConfigParam.getNotifyUrl(); //异步通知地址，支付宝结果通知地址
        String returnUrl = aliConfigParam.getReturnUrl(); //支付完成返回商户地址

        //支付宝SDK客户端
        DefaultAlipayClient alipayClient = new DefaultAlipayClient(gateway, appId, rsaPrivateKey, format, charset, alipayPublicKey, signType);
        // 封装请求支付信息
        AlipayTradeWapPayRequest wapPayRequest = new AlipayTradeWapPayRequest();
        AlipayTradeWapPayModel wapPayModel = new AlipayTradeWapPayModel();

        wapPayModel.setOutTradeNo(alipayBean.getOutTradeNo()); //惠民平台订单
        wapPayModel.setSubject(alipayBean.getSubject()); //订单标题
        wapPayModel.setTotalAmount(alipayBean.getTotalAmount()); //订单金额
        wapPayModel.setBody(alipayBean.getBody()); //订单描述
        wapPayModel.setProductCode(alipayBean.getProductCode()); //支付方式,固定值 QUICK_WAP_PAY
        wapPayModel.setTimeoutExpress(alipayBean.getExpireTime()); //支付超时时间

        wapPayRequest.setBizModel(wapPayModel); //设置请求参数
        String jsonString = JSON.toJSONString(alipayBean);
        log.info("支付宝请求参数:{}", jsonString);

        // 设置异步通知地址
        wapPayRequest.setNotifyUrl(notifyUrl);
        // 设置同步通知地址
        wapPayRequest.setReturnUrl(returnUrl);

        try {
            // 调用SDK生成表单
            AlipayTradeWapPayResponse wapPayResponse = alipayClient.pageExecute(wapPayRequest);
            log.info("支付宝手机网站支付预支付订单信息:{}", wapPayResponse);
            PaymentResponseDTO responseDTO = new PaymentResponseDTO();
            responseDTO.setContent(wapPayResponse.getBody());


            //向MQ发送一条延迟消息，到时间查询支付状态
            PaymentResponseDTO<AliConfigParam> notice = new PaymentResponseDTO<AliConfigParam>();
            notice.setOutTradeNo(alipayBean.getOutTradeNo()); //惠民平台订单号
            notice.setContent(aliConfigParam);
            notice.setMsg("ALIPAY_WAP"); //标识是查询支付宝的接口
            //发送消息
            payProducer.payOrderNotice(notice);


            return responseDTO;
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new BusinessException(CommonErrorCode.E_400002); // 支付宝确认支付失败
        }

    }

    /**
     * 调用支付宝手机WAP查询接口，查询支付宝交易状态
     *
     * @param aliConfigParam 支付渠道参数
     * @param outTradeNo     商户订单号
     * @return 支付响应结果
     * @throws BusinessException
     */
    @Override
    public PaymentResponseDTO queryPayOrderByAliWAP(AliConfigParam aliConfigParam, String outTradeNo) throws BusinessException {
        //获取支付宝渠道参数
        String gateway = aliConfigParam.getUrl(); //支付宝下单接口地址,支付宝网关
        String appId = aliConfigParam.getAppId(); //支付宝应用ID
        String rsaPrivateKey = aliConfigParam.getRsaPrivateKey(); //沙箱应用私钥
        String format = aliConfigParam.getFormat(); //请求参数格式json
        String charset = aliConfigParam.getCharset(); //编码格式
        String alipayPublicKey = aliConfigParam.getAlipayPublicKey(); //支付宝公钥
        String signType = aliConfigParam.getSigntype(); //签名方式
        String returnUrl = aliConfigParam.getReturnUrl(); //支付成功跳转的url
        String notifyUrl = aliConfigParam.getNotifyUrl(); //支付结果异步通知地址URL

        // 构造支付宝SDK客户端
        DefaultAlipayClient alipayClient = new DefaultAlipayClient(gateway, appId, rsaPrivateKey, format, charset, alipayPublicKey, signType);
        // 构造查询请求参数
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        // 封装请求参数
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(outTradeNo);//商户的订单，就是惠民平台的订单
        request.setBizModel(model);

        PaymentResponseDTO responseDTO = null; // 支付响应结果
        try {
            // 调用SDK查询订单
            AlipayTradeQueryResponse queryResponse = alipayClient.execute(request);
            log.info("支付宝查询订单结果:{}", queryResponse);
            // 订单状态码
            String code = queryResponse.getCode();
            if (AliCodeConstants.SUCCESSCODE.equals(code)) {
                String aliPayTradeStatus = queryResponse.getTradeStatus();
                // 将支付宝响应的状态转换成惠民平台的状态
                TradeStatus tradeStatus = convertAliTradeStatusToHuiminCode(aliPayTradeStatus);
                responseDTO = PaymentResponseDTO.success(queryResponse.getTradeNo(),
                        queryResponse.getOutTradeNo(),
                        tradeStatus,
                        queryResponse.getMsg() + " " + queryResponse.getSubMsg());

                log.info("‐‐‐‐查询支付宝H5支付结果" + JSON.toJSONString(responseDTO));
                return responseDTO;
            }
        } catch (AlipayApiException e) {
            log.warn("支付宝查询订单失败", e);
        }
        responseDTO = PaymentResponseDTO.fail("查询支付宝支付结果异常", outTradeNo, TradeStatus.UNKNOWN);
        return responseDTO;
    }

    /**
     * 解析支付宝的订单状态trade_status为惠民平台的状态
     *
     * @param aliTradeStatus 支付宝订单状态
     *                       WAIT_BUYER_PAY（交易创建，等待买家付款）
     *                       TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）
     *                       TRADE_SUCCESS（交易支付成功）
     *                       TRADE_FINISHED（交易结束，不可退款）
     * @return 支付状态
     */
    private TradeStatus convertAliTradeStatusToHuiminCode(String aliTradeStatus) {
        switch (aliTradeStatus) {
            case AliCodeConstants.TRADE_FINISHED:
            case AliCodeConstants.TRADE_SUCCESS:
                return TradeStatus.SUCCESS; //业务交易支付 明确支付成功
            case AliCodeConstants.TRADE_CLOSED:
                return TradeStatus.REVOKED; //交易撤销
            case AliCodeConstants.WAIT_BUYER_PAY:
                return TradeStatus.USERPAYING; //新建交易，等待支付
            default:
                return TradeStatus.FAILED; //支付失败
        }
    }


}
